<?php
/**
 * Abstract Request Bootstrap Class.
 * Enables dispatch to return for a variety of situations e.g. AJAX calls, HTTP, Unit Testing etc
 *
 * @author mpike
 */
abstract class Bootstrap{

	/**
	 * Load Core Files and Resources
	 */
	protected function loadCoreResources(){
		require_once("DirectoryManager.php");
		require_once("Request.php");
		require_once("Filter.php");
		require_once("Controller.php");
		require_once("Database.php");
		require_once("exceptions/BadRequest.php");

		DirectoryManager::$pathSrc = str_replace("\\","/",realpath(dirname(__FILE__)."/../"));
		DirectoryManager::$pathCore = DirectoryManager::$pathSrc."/core";
		DirectoryManager::$pathModels = DirectoryManager::$pathSrc."/models";
		DirectoryManager::$pathViews = DirectoryManager::$pathSrc."/views";
		$count = strrpos(DirectoryManager::$pathSrc, "/src");
		DirectoryManager::$pathUnitTests = substr(DirectoryManager::$pathSrc,0,$count)."/unit_tests";

	}

	/**
	 * Call a controller action
	 *
	 * @param string $controller
	 * @param string $action
	 * @param array $params
	 * @return mixed
	 */
	protected function callAction($controller,$action,$params){
		if(!$action) $action = "index";
		return call_user_func(array($controller,$action."Action"),$params);
	}

	/**
	 * Does Controller Action Exist
	 *
	 * @param $controller
	 * @param $action
	 */
	protected function actionExists($controller,$action){
		return method_exists($controller,$action."Action");
	}

	/**
	 * Loads Controller And Validates
	 *
	 * @param string
	 * @throws BadRequest
	 * @return boolean
	 */
	protected function loadController($controller){
		if(file_exists(DirectoryManager::$pathSrc."/controllers/{$controller}.php")){
			require_once(DirectoryManager::$pathSrc."/controllers/{$controller}.php");
			return (class_exists($controller,false) && is_subclass_of($controller,"Controller"));
		}else{
			throw new BadRequest("Unsupported controller: c=$controller");
		}
	}

	/**
	 * Dispatch a request to the relevant controller+action.
	 * Also responsible for handling any application level errors.
	 *
	 * @param $_REQUEST
	 * @return mixed Depends on the context
	 */
	abstract public function dispatchRequest(array $request);
}